package services

import (
	"context"
	"errors"
	"github.com/ethereum/go-ethereum/accounts/abi"
	"github.com/ethereum/go-ethereum/accounts/abi/bind"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethclient"
	"log"
	"math/big"
	"src/conf/database"
	"src/constant"
	"src/entity"
	"src/req"
	"strings"
	"time"
)

/*
@date : 2024/8/28 13:34
@author : mie
@desc: pancakeSwap v2 的交易
*/

func TransactionV2(req *req.SwapTransactionReq) error {
	//senderAddress := req.SenderAddress
	tokenIn, tokenTo, amountInWei, gasLimit, senderAddress := req.TokenIn, req.TokenTo, req.AmountInWei, req.GasLimit, req.SenderAddress
	chainID := big.NewInt(56)

	db := database.InitDatabase()
	var uw entity.UserWallet
	db.Debug().Where("address=?", senderAddress).First(&uw)
	var privateKey = uw.PrivateKey //从数据库获取

	if strings.TrimSpace(privateKey) == "" {
		return errors.New("当前钱包私钥为空无法交易")
	}

	// 连接到 BSC 网络
	client, err := ethclient.Dial("https://bsc-dataseed.binance.org/")
	if err != nil {
		return err
	}
	defer client.Close()

	// 解析私钥
	pk, err := crypto.HexToECDSA(privateKey)
	if err != nil {
		return err
	}

	// 获取钱包地址
	fromAddress := crypto.PubkeyToAddress(pk.PublicKey)

	// 创建 auth 对象
	auth, err := bind.NewKeyedTransactorWithChainID(pk, chainID)
	if err != nil {
		return err
	}

	// 设置 gas 费用
	//auth.GasLimit = uint64(200000) // gas limit
	auth.GasLimit = uint64(gasLimit) // gas limit
	auth.GasPrice, err = client.SuggestGasPrice(context.Background())
	if err != nil {
		return err
	}

	// 获取 nonce
	nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
	if err != nil {
		return err
	}
	auth.Nonce = big.NewInt(int64(nonce))

	// Router 合约地址
	routerAddress := common.HexToAddress("0x10ED43C718714eb63d5aA57B78B54704E256024E")

	// 定义 Router 合约的 ABI
	//PancakeRouterABI := `[{"inputs":[...],"name":"swapExactTokensForTokens","outputs":[...],"stateMutability":"nonpayable","type":"function"}]` // 请使用真实的 ABI

	// 解析 ABI
	routerAbi, err := abi.JSON(strings.NewReader(constant.PancakeRouterV2ABI))
	if err != nil {
		return err
	}

	// 准备交易数据
	tokenInAddress := common.HexToAddress(tokenIn)
	tokenOutAddress := common.HexToAddress(tokenTo)
	amountOutMin := big.NewInt(0) // 设定一个最低接收量，通常为0或略低于预期
	path := []common.Address{tokenInAddress, tokenOutAddress}
	to := fromAddress
	deadline := big.NewInt(time.Now().Add(time.Minute * 10).Unix()) // 设置一个10分钟后的截止时间

	input, err := routerAbi.Pack("swapExactTokensForTokens", amountInWei, amountOutMin, path, to, deadline)
	if err != nil {
		return err
	}

	// 创建交易，使用 types.NewTx 代替
	tx := types.NewTx(&types.LegacyTx{
		Nonce:    nonce,
		To:       &routerAddress,
		Value:    big.NewInt(0),
		Gas:      auth.GasLimit,
		GasPrice: auth.GasPrice,
		Data:     input,
	})

	// 签署交易
	signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(chainID), pk)
	if err != nil {
		return err
	}

	// 发送交易
	err = client.SendTransaction(context.Background(), signedTx)
	if err != nil {
		return err
	}

	log.Printf("Transaction sent: %s", signedTx.Hash().Hex())

	// 等待交易确认
	receipt, err := client.TransactionReceipt(context.Background(), signedTx.Hash())
	if err != nil {
		return err
	}

	log.Printf("Transaction receipt: %v", receipt.Status)

	return nil

}
